package com.sardine.base.esm.mapper;

import com.sardine.base.esm.session.Configuration;
import com.sardine.base.esm.support.EsmSessionDaoSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.FactoryBean;

import static org.springframework.util.Assert.notNull;

/**
 * 上海京东到家元信信息技术有限公司<br>
 * Created with IntelliJ IDEA.
 * Date:2017/5/23
 * Time:16:15
 * esm的映射工厂bean，他是具体接口的实现
 *
 * @author daifeng<br>
 *         daifeng@imdada.cn
 * @since JDK 1.7 <br>
 * Copyright (c) 2017 imdada System Incorporated All Rights Reserved.
 */
public class EsmMapperFactoryBean<T> extends EsmSessionDaoSupport implements FactoryBean<T> {
    private static final Logger logger = LoggerFactory.getLogger(EsmMapperFactoryBean.class);
    //被映射的接口
    private Class<T> mapperInterface;

    /**
     * 设置接口属性，在scanner 扫描的时候，通过spring注入到这个类中
     *
     * @param mapperInterface
     */
    public void setMapperInterface(Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
    }

    /**
     * 检查DAO的配置。必须满足有  mapperInterface 信息，该方法在属性加载完成后调用
     */
    @Override
    protected void checkDaoConfig() {
        super.checkDaoConfig();

        notNull(this.mapperInterface, "Property 'mapperInterface' is required");
        //得到配置相关信息
        Configuration configuration = getEsmSession().getConfiguration();
        //如果配置总不含有该接口的映射，则添加这个映射接口到配置对象
        if (!configuration.hasMapper(this.mapperInterface)) {
            try {
                //设置接口代理对象
                configuration.addMapper(this.mapperInterface);
            } catch (Throwable t) {
                logger.error("Error while adding the mapper '" + this.mapperInterface + "' to configuration.", t);
                throw new IllegalArgumentException(t);
            }
        }
    }


    @Override
    public T getObject() throws Exception {
        return getEsmSession().getMapper(this.mapperInterface);
    }

    @Override
    public Class<?> getObjectType() {
        return this.mapperInterface;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}
